using System.Collections.Generic;
using System.Text;

namespace MvpFramework
{
    public class Navigator:INavigator
    {
        private readonly IMvpViewLocationRepository _repository;
        private readonly IHttpResponse _response;
        private const string optionsBeginCharacter = "?";
        private const string optionsFormat = "{0}={1}";
        private const string optionsDeliminator = "&";

        
        internal Navigator(IHttpResponse response, IMvpViewLocationRepository repository)
        {
            _response = response;
            _repository = repository;
        }

        #region Implementation of INavigator

        /// <summary>
        /// Navigates to the location specified
        /// </summary>
        /// <param name="location"></param>
        public virtual void NavigateTo(string location)
        {
            _response.Redirect(location);
        }

        /// <summary>
        /// Will navigate to the <see cref="IMvpView"/> specified with the options sent.
        /// </summary>
        /// <typeparam name="IMvpView"></typeparam>
        /// <param name="options"></param>
        public virtual void NavigateTo<IMvpView>(Dictionary<string, object> options)
        {
            var location = _repository.GetLocationFor<IMvpView>();
            var redirectTo = GetRedirectToWithOptions(location, options);
            NavigateTo(redirectTo);
        }

        private static string GetRedirectToWithOptions(string location, Dictionary<string, object> options)
        {
            var builder = new StringBuilder(location);
            builder.Append(optionsBeginCharacter);
            foreach (var item in options)
            {
                builder.AppendFormat(optionsFormat, item.Key, item.Value);
                builder.Append(optionsDeliminator);
            }
            //Remove the trailing &
            return builder.ToString(0, builder.Length - 1);
        }

        /// <summary>
        /// Will navigate to the <see cref="IMvpView"/> specified.
        /// </summary>
        /// <typeparam name="IMvpView"></typeparam>
        public virtual void NavigateTo<IMvpView>()
        {
            var location = _repository.GetLocationFor<IMvpView>();
            NavigateTo(location);
        }

        #endregion
    }
}